package com.tbynet.jwp.repository.impl;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.tbynet.jwp.framework.aop.Aop;
import com.tbynet.jwp.framework.core.JwpRepository;
import com.tbynet.jwp.framework.exception.RepositoryException;
import com.tbynet.jwp.framework.kit.SlugKit;
import com.tbynet.jwp.model.TermTaxonomy;
import com.tbynet.jwp.model.Terms;
import com.tbynet.jwp.model.Termmeta;
import com.tbynet.jwp.repository.spi._TermCommandRepository;
import com.tbynet.jwp.repository.dto.command.TermCreateCommand;
import com.tbynet.jwp.repository.dto.command.TermUpdateCommand;

import java.math.BigInteger;
import java.util.List;

/**
 * 分类项命令仓储实现类
 * 负责分类项的创建、更新、删除等写操作
 *
 * 注意：Repository层无事务，事务在Service层控制
 * 异常处理原则：
 * - 数据访问异常抛出 RepositoryException
 *
 * @author 佰亿互联
 * @version 1.0
 * @since 2025-11-04
 */
@Aop(_TermCommandRepository.class)
public class _TermCommandRepositoryImpl extends JwpRepository implements _TermCommandRepository {

    /**
     * 创建分类项
     *
     * @param command 创建命令参数
     * @return 新创建的分类项ID
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public BigInteger createTerm(TermCreateCommand command) {
        // 参数验证
        validateCreateCommand(command);

        return executeDataOperation("创建分类项", () -> {
            // 生成别名（如果未提供）
            String slug = command.getSlug();
            if (StrKit.isBlank(slug)) {
                slug = SlugKit.slugify(command.getName());
            }

            // 验证别名唯一性
            if (isSlugExists(slug, command.getTaxonomy(), null)) {
                throw new RepositoryException(String.format("分类项别名已存在: slug=%s, taxonomy=%s", slug, command.getTaxonomy()));
            }

            // 保存分类项（Terms表）
            Terms term = new Terms();
            term.setName(command.getName());
            term.setSlug(slug);
            term.setTermGroup(0L);
            if (!term.save()) {
                throw new RepositoryException("保存分类项",
                        new RuntimeException("数据库保存失败，可能违反唯一约束"));
            }

            // 保存分类法（TermTaxonomy表）
            TermTaxonomy taxonomy = new TermTaxonomy();
            taxonomy.setTermId(term.getTermId());
            taxonomy.setTaxonomy(command.getTaxonomy());
            taxonomy.setDescription(command.getDescription() != null ? command.getDescription() : "");
            taxonomy.setParent(command.getParentId() != null ? command.getParentId() : BigInteger.ZERO);
            taxonomy.setCount(0L);
            if (!taxonomy.save()) {
                throw new RepositoryException("保存分类法",
                        new RuntimeException("数据库保存失败"));
            }

            log.info("创建分类项成功，ID: %s, 名称: %s, 分类法: %s",
                    term.getTermId(), command.getName(), command.getTaxonomy());

            return term.getTermId();
        });
    }

    /**
     * 更新分类项
     *
     * @param command 更新命令参数
     * @return 更新是否成功
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public boolean updateTerm(TermUpdateCommand command) {
        // 参数验证
        validateUpdateCommand(command);

        return executeDataOperation("更新分类项", () -> {
            // 获取现有分类项
            Terms term = Terms.dao.findById(command.getTermId());
            if (term == null) {
                throw new RepositoryException("分类项不存在").withContext("term_id", command.getTermId());
            }

            boolean hasUpdate = false;

            // 更新Terms表
            if (StrKit.notBlank(command.getName())) {
                term.setName(command.getName());
                hasUpdate = true;
            }
            if (StrKit.notBlank(command.getSlug())) {
                // 验证新别名的唯一性（排除当前分类项）
                if (isSlugExists(command.getSlug(), command.getTaxonomy(), command.getTermId())) {
                    throw new RepositoryException("分类项别名已存在").withContext("slug", command.getSlug());
                }
                term.setSlug(command.getSlug());
                hasUpdate = true;
            }

            if (hasUpdate && !term.update()) {
                throw new RepositoryException("更新分类项",
                        new RuntimeException("数据库更新失败"));
            }

            // 更新TermTaxonomy表
            TermTaxonomy taxonomy = TermTaxonomy.dao.findFirst(
                    "SELECT * FROM wp_term_taxonomy WHERE term_id = ?", command.getTermId());
            if (taxonomy == null) {
                throw new RepositoryException("分类法不存在").withContext("term_id", command.getTermId());
            }

            boolean taxonomyUpdated = false;
            if (StrKit.notBlank(command.getTaxonomy())) {
                taxonomy.setTaxonomy(command.getTaxonomy());
                taxonomyUpdated = true;
            }
            if (StrKit.notBlank(command.getDescription())) {
                taxonomy.setDescription(command.getDescription());
                taxonomyUpdated = true;
            }
            if (command.getParentId() != null) {
                taxonomy.setParent(command.getParentId());
                taxonomyUpdated = true;
            }

            if (taxonomyUpdated && !taxonomy.update()) {
                throw new RepositoryException("更新分类法",
                        new RuntimeException("数据库更新失败"));
            }

            log.debug("更新分类项成功，ID: %s, 分类法: %s", command.getTermId(), command.getTaxonomy());
            return true;
        });
    }

    /**
     * 删除分类项
     *
     * @param termId 分类项ID
     * @param taxonomy 分类法类型
     * @return 删除是否成功
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public boolean deleteTerm(BigInteger termId, String taxonomy) {
        // 参数验证
        validateTermId(termId);
        validateTaxonomy(taxonomy);

        return executeDataOperation("删除分类项", () -> {
            // 检查分类项是否存在
            TermTaxonomy termTaxonomy = TermTaxonomy.dao.findFirst(
                    "SELECT * FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = ?", termId, taxonomy);
            if (termTaxonomy == null) {
                throw new RepositoryException("分类法不存在").withContext("term_id", termId).withContext("taxonomy", taxonomy);
            }

            // 检查是否有文章关联
            if (termTaxonomy.getCount() > 0) {
                throw new RepositoryException("分类项有关联文章，无法删除").withContext("term_id", termId);
            }

            // 检查是否有子分类项
            List<TermTaxonomy> childTaxonomies = TermTaxonomy.dao.find(
                    "SELECT * FROM wp_term_taxonomy WHERE parent = ? AND taxonomy = ?", termId, taxonomy);
            if (childTaxonomies != null && !childTaxonomies.isEmpty()) {
                throw new RepositoryException("分类项有子分类项，无法删除").withContext("term_id", termId);
            }

            // 删除分类项元数据
            Db.delete("DELETE FROM wp_termmeta WHERE term_id = ?", termId);

            // 删除分类关系
            Db.delete("DELETE FROM wp_term_relationships WHERE term_taxonomy_id = ?",
                    termTaxonomy.getTermTaxonomyId());

            // 删除分类法记录
            boolean taxonomyDeleted = termTaxonomy.delete();
            if (!taxonomyDeleted) {
                throw new RepositoryException("删除分类法记录",
                        new RuntimeException("数据库删除失败"));
            }

            // 删除分类项记录
            boolean termDeleted = Terms.dao.deleteById(termId);
            if (!termDeleted) {
                throw new RepositoryException("删除分类项记录",
                        new RuntimeException("数据库删除失败"));
            }

            log.info("删除分类项成功，term_id: %s, taxonomy: %s", termId, taxonomy);
            return true;
        });
    }

    /**
     * 批量删除分类项
     *
     * @param termIds 分类项ID列表
     * @param taxonomy 分类法类型
     * @return 成功删除的数量
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public Integer batchDeleteTerms(List<BigInteger> termIds, String taxonomy) {
        // 参数验证
        if (termIds == null || termIds.isEmpty()) {
            throw new RepositoryException("分类项ID列表不能为空").withContext("termIds", termIds);
        }
        if (StrKit.isBlank(taxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", taxonomy);
        }

        return executeDataOperation("批量删除分类项", () -> {
            int successCount = 0;
            for (BigInteger termId : termIds) {
                try {
                    if (deleteTerm(termId, taxonomy)) {
                        successCount++;
                    }
                } catch (RepositoryException e) {
                    // 跳过但不计入失败
                    log.warn("批量删除时异常，跳过: termId=%s, error=%s", termId, e.getMessage());
                }
            }

            log.info("批量删除分类项完成，总数: %s, 成功: %s, 分类法: %s",
                    termIds.size(), successCount, taxonomy);
            return successCount;
        });
    }

    /**
     * 设置分类项元数据
     *
     * @param termId 分类项ID
     * @param metaKey 元数据键
     * @param metaValue 元数据值
     * @return 设置是否成功
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public boolean setTermMeta(BigInteger termId, String metaKey, Object metaValue) {
        // 参数验证
        if (termId == null) {
            throw new RepositoryException("分类项ID不能为空").withContext("termId", termId);
        }
        if (StrKit.isBlank(metaKey)) {
            throw new RepositoryException("元数据键不能为空").withContext("metaKey", metaKey);
        }

        return executeDataOperation("设置分类项元数据", () -> {
            // 检查分类项是否存在
            Terms term = Terms.dao.findById(termId);
            if (term == null) {
                throw new RepositoryException("分类项不存在").withContext("termId", termId);
            }

            // 检查元数据是否已存在
            Record metaRecord = Db.findFirst(
                    "SELECT * FROM wp_termmeta WHERE term_id = ? AND meta_key = ?", termId, metaKey);

            if (metaRecord != null) {
                // 更新元数据
                metaRecord.set("meta_value", metaValue);
                boolean updated = Db.update("wp_termmeta", "meta_id", metaRecord);
                if (!updated) {
                    throw new RepositoryException("更新分类项元数据",
                            new RuntimeException("数据库更新失败"));
                }
                log.debug("更新分类项元数据，term_id: %s, meta_key: %s", termId, metaKey);
            } else {
                // 插入新元数据
                Termmeta newMeta = new Termmeta();
                newMeta.setTermId(termId);
                newMeta.setMetaKey(metaKey);
                newMeta.setMetaValue(String.valueOf(metaValue));
                boolean saved = newMeta.save();
                if (!saved) {
                    throw new RepositoryException("新增分类项元数据",
                            new RuntimeException("数据库插入失败"));
                }
                log.debug("新增分类项元数据，term_id: %s, meta_key: %s", termId, metaKey);
            }

            return true;
        });
    }

    /**
     * 删除分类项元数据
     *
     * @param termId 分类项ID
     * @param metaKey 元数据键
     * @return 删除是否成功
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public boolean deleteTermMeta(BigInteger termId, String metaKey) {
        // 参数验证
        if (termId == null) {
            throw new RepositoryException("分类项ID不能为空").withContext("termId", termId);
        }
        if (StrKit.isBlank(metaKey)) {
            throw new RepositoryException("元数据键不能为空").withContext("metaKey", metaKey);
        }

        return executeDataOperation("删除分类项元数据", () -> {
            int rows = Db.delete("DELETE FROM wp_termmeta WHERE term_id = ? AND meta_key = ?", termId, metaKey);
            boolean success = rows > 0;

            if (success) {
                log.debug("删除分类项元数据成功，term_id: %s, meta_key: %s", termId, metaKey);
            } else {
                log.debug("分类项元数据不存在，无需删除，term_id: %s, meta_key: %s", termId, metaKey);
            }

            return success;
        });
    }

    /**
     * 更新分类项计数
     *
     * @param termId 分类项ID
     * @param taxonomy 分类法类型
     * @return 更新是否成功
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public boolean updateTermCount(BigInteger termId, String taxonomy) {
        // 参数验证
        if (termId == null) {
            throw new RepositoryException("分类项ID不能为空").withContext("termId", termId);
        }
        if (StrKit.isBlank(taxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", taxonomy);
        }

        return executeDataOperation("更新分类项计数", () -> {
            // 检查分类项是否存在
            TermTaxonomy termTaxonomy = TermTaxonomy.dao.findFirst(
                    "SELECT * FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = ?", termId, taxonomy);
            if (termTaxonomy == null) {
                throw new RepositoryException("分类法不存在").withContext("termId", termId).withContext("taxonomy", taxonomy);
            }

            // 查询分类项关联的文章数量
            String countSql = "SELECT COUNT(*) as post_count FROM wp_term_relationships tr " +
                    "INNER JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id " +
                    "WHERE tt.term_id = ? AND tt.taxonomy = ?";

            Record countRecord = Db.findFirst(countSql, termId, taxonomy);
            if (countRecord == null) {
                throw new RepositoryException("查询分类项计数",
                        new RuntimeException("查询结果为空"));
            }

            Long postCount = countRecord.getLong("post_count");

            // 更新分类项计数
            String updateSql = "UPDATE wp_term_taxonomy SET count = ? WHERE term_id = ? AND taxonomy = ?";
            int updated = Db.update(updateSql, postCount, termId, taxonomy);

            boolean success = updated > 0;
            if (!success) {
                throw new RepositoryException("更新分类项计数",
                        new RuntimeException("数据库更新失败"));
            }

            log.debug("更新分类项计数成功，term_id: %s, count: %s, taxonomy: %s", termId, postCount, taxonomy);
            return true;
        });
    }

    /**
     * 清理空分类项
     *
     * @param taxonomy 分类法类型
     * @return 清理的数量
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public Integer cleanupUnusedTerms(String taxonomy) {
        // 参数验证
        if (StrKit.isBlank(taxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", taxonomy);
        }

        return executeDataOperation("清理空分类项", () -> {
            // 查找空分类项（count = 0）
            String findSql = "SELECT tt.term_taxonomy_id, tt.term_id FROM wp_term_taxonomy tt " +
                    "WHERE tt.taxonomy = ? AND tt.count = 0";

            List<Record> unusedTerms = Db.find(findSql, taxonomy);
            if (unusedTerms.isEmpty()) {
                log.debug("没有找到空分类项，taxonomy: %s", taxonomy);
                return 0;
            }

            int deletedCount = 0;
            for (Record record : unusedTerms) {
                Long termId = record.getLong("term_id");
                Long taxonomyId = record.getLong("term_taxonomy_id");

                try {
                    // 删除元数据
                    Db.delete("DELETE FROM wp_termmeta WHERE term_id = ?", termId);

                    // 删除分类法记录
                    Db.delete("DELETE FROM wp_term_taxonomy WHERE term_taxonomy_id = ?", taxonomyId);

                    // 删除分类项记录
                    boolean termDeleted = Terms.dao.deleteById(termId);

                    if (termDeleted) {
                        deletedCount++;
                    }
                } catch (Exception e) {
                    log.warn("删除空分类项失败，term_id: %s, 跳过", termId, e);
                }
            }

            log.info("清理空分类项完成，taxonomy: %s, 清理数量: %s", taxonomy, deletedCount);
            return deletedCount;
        });
    }

    /**
     * 合并分类项
     *
     * @param sourceTermId 源分类项ID
     * @param targetTermId 目标分类项ID
     * @param taxonomy 分类法类型
     * @return 合并是否成功
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public boolean mergeTerms(BigInteger sourceTermId, BigInteger targetTermId, String taxonomy) {
        // 参数验证
        if (sourceTermId == null || targetTermId == null) {
            throw new RepositoryException("分类项ID不能为空").withContext("sourceTermId", sourceTermId);
        }
        if (StrKit.isBlank(taxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", taxonomy);
        }
        if (sourceTermId.equals(targetTermId)) {
            throw new RepositoryException("源分类项和目标分类项不能相同").withContext("sourceTermId", sourceTermId).withContext("targetTermId", targetTermId);
        }

        return executeDataOperation("合并分类项", () -> {
            // 检查分类项是否存在
            TermTaxonomy sourceTaxonomy = TermTaxonomy.dao.findFirst(
                    "SELECT * FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = ?",
                    sourceTermId, taxonomy);
            TermTaxonomy targetTaxonomy = TermTaxonomy.dao.findFirst(
                    "SELECT * FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = ?",
                    targetTermId, taxonomy);

            if (sourceTaxonomy == null) {
                throw new RepositoryException("源分类法不存在").withContext("termId", sourceTermId).withContext("taxonomy", taxonomy);
            }
            if (targetTaxonomy == null) {
                throw new RepositoryException("目标分类法不存在").withContext("termId", targetTermId).withContext("taxonomy", taxonomy);
            }

            // 转移关联关系
            String updateRelationshipsSql = "UPDATE wp_term_relationships " +
                    "SET term_taxonomy_id = ? " +
                    "WHERE term_taxonomy_id = ?";
            int updatedRelationships = Db.update(updateRelationshipsSql,
                    targetTaxonomy.getTermTaxonomyId(), sourceTaxonomy.getTermTaxonomyId());

            // 更新目标分类项计数
            Long newCount = targetTaxonomy.getCount() + sourceTaxonomy.getCount();
            targetTaxonomy.setCount(newCount);
            if (!targetTaxonomy.update()) {
                throw new RepositoryException("更新目标分类项计数",
                        new RuntimeException("数据库更新失败"));
            }

            // 删除源分类项
            boolean sourceDeleted = deleteTerm(sourceTermId, taxonomy);
            if (!sourceDeleted) {
                throw new RepositoryException("删除源分类项",
                        new RuntimeException("删除操作失败"));
            }

            log.info("合并分类项成功，源: %s, 目标: %s, 转移关系: %s",
                    sourceTermId, targetTermId, updatedRelationships);
            return true;
        });
    }

    /**
     * 设置默认分类项
     *
     * @param taxonomy 分类法类型
     * @param termId 分类项ID
     * @return 设置是否成功
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public boolean setDefaultTerm(String taxonomy, BigInteger termId) {
        // 参数验证
        if (StrKit.isBlank(taxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", taxonomy);
        }
        if (termId == null) {
            throw new RepositoryException("分类项ID不能为空").withContext("termId", termId);
        }

        return executeDataOperation("设置默认分类项", () -> {
            // 检查分类项是否存在
            TermTaxonomy termTaxonomy = TermTaxonomy.dao.findFirst(
                    "SELECT * FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = ?",
                    termId, taxonomy);
            if (termTaxonomy == null) {
                throw new RepositoryException("分类法不存在").withContext("termId", termId).withContext("taxonomy", taxonomy);
            }

            // 保存到系统选项（模拟WordPress的default_category选项）
            String optionName = "default_" + taxonomy;
            Record option = Db.findFirst("SELECT * FROM wp_options WHERE option_name = ?", optionName);

            if (option != null) {
                // 更新现有选项
                option.set("option_value", termId.toString());
                boolean updated = Db.update("wp_options", "option_id", option);
                if (!updated) {
                    throw new RepositoryException("更新默认分类项选项",
                            new RuntimeException("数据库更新失败"));
                }
                log.debug("更新默认分类项选项，taxonomy: %s, termId: %s", taxonomy, termId);
            } else {
                // 创建新选项
                Record newOption = new Record()
                        .set("option_name", optionName)
                        .set("option_value", termId.toString())
                        .set("autoload", "yes");
                boolean saved = Db.save("wp_options", newOption);
                if (!saved) {
                    throw new RepositoryException("创建默认分类项选项",
                            new RuntimeException("数据库插入失败"));
                }
                log.debug("创建默认分类项选项，taxonomy: %s, termId: %s", taxonomy, termId);
            }

            return true;
        });
    }

    /**
     * 转换分类项
     *
     * @param termId 分类项ID
     * @param sourceTaxonomy 源分类法类型
     * @param targetTaxonomy 目标分类法类型
     * @return 转换后的分类项ID
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public BigInteger transformTerm(BigInteger termId, String sourceTaxonomy, String targetTaxonomy) {
        // 参数验证
        if (termId == null) {
            throw new RepositoryException("分类项ID不能为空").withContext("termId", termId);
        }
        if (StrKit.isBlank(sourceTaxonomy) || StrKit.isBlank(targetTaxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("sourceTaxonomy", sourceTaxonomy);
        }
        if (sourceTaxonomy.equals(targetTaxonomy)) {
            throw new RepositoryException("源分类法和目标分类法不能相同").withContext("sourceTaxonomy", sourceTaxonomy).withContext("targetTaxonomy", targetTaxonomy);
        }

        return executeDataOperation("转换分类项", () -> {
            // 获取源分类项
            Terms term = Terms.dao.findById(termId);
            if (term == null) {
                throw new RepositoryException("分类项不存在").withContext("termId", termId);
            }

            TermTaxonomy sourceTermTaxonomy = TermTaxonomy.dao.findFirst(
                    "SELECT * FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = ?",
                    termId, sourceTaxonomy);
            if (sourceTermTaxonomy == null) {
                throw new RepositoryException("源分类法不存在").withContext("termId", termId).withContext("taxonomy", sourceTaxonomy);
            }

            // 检查目标分类法是否已存在相同分类项
            TermTaxonomy existingTarget = TermTaxonomy.dao.findFirst(
                    "SELECT * FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = ?",
                    termId, targetTaxonomy);
            if (existingTarget != null) {
                throw new RepositoryException("目标分类法已存在相同分类项").withContext("termId", termId).withContext("taxonomy", targetTaxonomy);
            }

            // 创建目标分类法记录
            TermTaxonomy targetTermTaxonomy = new TermTaxonomy();
            targetTermTaxonomy.setTermId(termId);
            targetTermTaxonomy.setTaxonomy(targetTaxonomy);
            targetTermTaxonomy.setDescription(sourceTermTaxonomy.getDescription());
            targetTermTaxonomy.setParent(sourceTermTaxonomy.getParent());
            targetTermTaxonomy.setCount(sourceTermTaxonomy.getCount());

            if (!targetTermTaxonomy.save()) {
                throw new RepositoryException("创建目标分类法",
                        new RuntimeException("数据库保存失败"));
            }

            // 复制元数据
            List<Record> sourceMeta = Db.find(
                    "SELECT meta_key, meta_value FROM wp_termmeta WHERE term_id = ?", termId);
            for (Record meta : sourceMeta) {
                Record newMeta = new Record()
                        .set("term_id", termId)
                        .set("meta_key", meta.getStr("meta_key"))
                        .set("meta_value", meta.get("meta_value"));
                Db.save("wp_termmeta", newMeta);
            }

            log.info("转换分类项成功，term_id: %s, 源: %s, 目标: %s",
                    termId, sourceTaxonomy, targetTaxonomy);
            return termId;
        });
    }

    /**
     * 复制分类项
     *
     * @param termId 源分类项ID
     * @param newName 新分类项名称
     * @param taxonomy 分类法类型
     * @return 新分类项ID
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public BigInteger duplicateTerm(BigInteger termId, String newName, String taxonomy) {
        // 参数验证
        if (termId == null) {
            throw new RepositoryException("分类项ID不能为空").withContext("termId", termId);
        }
        if (StrKit.isBlank(newName)) {
            throw new RepositoryException("新分类项名称不能为空").withContext("newName", newName);
        }
        if (StrKit.isBlank(taxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", taxonomy);
        }

        return executeDataOperation("复制分类项", () -> {
            // 获取源分类项
            Terms sourceTerm = Terms.dao.findById(termId);
            if (sourceTerm == null) {
                throw new RepositoryException("源分类项不存在").withContext("termId", termId);
            }

            TermTaxonomy sourceTaxonomy = TermTaxonomy.dao.findFirst(
                    "SELECT * FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = ?",
                    termId, taxonomy);
            if (sourceTaxonomy == null) {
                throw new RepositoryException("源分类法不存在").withContext("termId", termId).withContext("taxonomy", taxonomy);
            }

            // 检查新名称是否已存在
            Terms existingTerm = Terms.dao.findFirst(
                    "SELECT * FROM wp_terms WHERE name = ?", newName);
            if (existingTerm != null) {
                throw new RepositoryException("分类项名称已存在").withContext("name", newName);
            }

            // 生成唯一别名
            String newSlug = generateUniqueSlug(newName, taxonomy);

            // 创建新分类项
            Terms newTerm = new Terms();
            newTerm.setName(newName);
            newTerm.setSlug(newSlug);
            newTerm.setTermGroup(sourceTerm.getTermGroup());
            if (!newTerm.save()) {
                throw new RepositoryException("保存新分类项",
                        new RuntimeException("数据库保存失败"));
            }

            // 创建新分类法
            TermTaxonomy newTaxonomy = new TermTaxonomy();
            newTaxonomy.setTermId(newTerm.getTermId());
            newTaxonomy.setTaxonomy(taxonomy);
            newTaxonomy.setDescription(sourceTaxonomy.getDescription());
            newTaxonomy.setParent(sourceTaxonomy.getParent());
            newTaxonomy.setCount(0L); // 新分类项计数为0
            if (!newTaxonomy.save()) {
                // 回滚：删除刚保存的Terms记录
                Terms.dao.deleteById(newTerm.getTermId());
                throw new RepositoryException("保存新分类法",
                        new RuntimeException("数据库保存失败"));
            }

            // 复制元数据
            List<Record> sourceMeta = Db.find(
                    "SELECT meta_key, meta_value FROM wp_termmeta WHERE term_id = ?", termId);
            for (Record meta : sourceMeta) {
                Record newMeta = new Record()
                        .set("term_id", newTerm.getTermId())
                        .set("meta_key", meta.getStr("meta_key"))
                        .set("meta_value", meta.get("meta_value"));
                Db.save("wp_termmeta", newMeta);
            }

            log.info("复制分类项成功，源: %s, 新: %s, 名称: %s", termId, newTerm.getTermId(), newName);
            return newTerm.getTermId();
        });
    }

    /**
     * 重置分类项计数
     *
     * @param taxonomy 分类法类型
     * @return 更新计数的分类项数量
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public Integer resetTermCounts(String taxonomy) {
        // 参数验证
        if (StrKit.isBlank(taxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", taxonomy);
        }

        return executeDataOperation("重置分类项计数", () -> {
            // 获取所有分类项
            List<TermTaxonomy> taxonomies = TermTaxonomy.dao.find(
                    "SELECT * FROM wp_term_taxonomy WHERE taxonomy = ?", taxonomy);

            int updatedCount = 0;
            for (TermTaxonomy termTaxonomy : taxonomies) {
                // 查询实际的文章数量
                String countSql = "SELECT COUNT(*) as post_count FROM wp_term_relationships tr " +
                        "WHERE tr.term_taxonomy_id = ?";
                Record countRecord = Db.findFirst(countSql, termTaxonomy.getTermTaxonomyId());

                if (countRecord != null) {
                    Long actualCount = countRecord.getLong("post_count");
                    if (!actualCount.equals(termTaxonomy.getCount())) {
                        termTaxonomy.setCount(actualCount);
                        if (termTaxonomy.update()) {
                            updatedCount++;
                        }
                    }
                }
            }

            log.info("重置分类项计数完成，taxonomy: %s, 更新数量: %s", taxonomy, updatedCount);
            return updatedCount;
        });
    }

    /**
     * 重新生成分类项别名
     *
     * @param termId 分类项ID
     * @param taxonomy 分类法类型
     * @return 新的别名
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public String regenerateTermSlug(BigInteger termId, String taxonomy) {
        // 参数验证
        if (termId == null) {
            throw new RepositoryException("分类项ID不能为空").withContext("termId", termId);
        }
        if (StrKit.isBlank(taxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", taxonomy);
        }

        return executeDataOperation("重新生成分类项别名", () -> {
            // 获取分类项
            Terms term = Terms.dao.findById(termId);
            if (term == null) {
                throw new RepositoryException("分类项不存在").withContext("termId", termId);
            }

            // 生成新别名
            String newSlug = generateUniqueSlug(term.getName(), taxonomy);

            // 更新别名
            term.setSlug(newSlug);
            if (!term.update()) {
                throw new RepositoryException("更新分类项别名",
                        new RuntimeException("数据库更新失败"));
            }

            log.info("重新生成分类项别名成功，term_id: %s, 新别名: %s", termId, newSlug);
            return newSlug;
        });
    }

    /**
     * 批量更新分类项父级
     *
     * @param termIds 分类项ID列表
     * @param parentId 父级分类项ID
     * @param taxonomy 分类法类型
     * @return 成功更新的数量
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public Integer batchUpdateParent(List<BigInteger> termIds, BigInteger parentId, String taxonomy) {
        // 参数验证
        if (termIds == null || termIds.isEmpty()) {
            throw new RepositoryException("分类项ID列表不能为空").withContext("termIds", termIds);
        }
        if (StrKit.isBlank(taxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", taxonomy);
        }

        return executeDataOperation("批量更新分类项父级", () -> {
            // 检查父级分类项是否存在（如果parentId不为空）
            if (parentId != null && !parentId.equals(BigInteger.ZERO)) {
                TermTaxonomy parentTaxonomy = TermTaxonomy.dao.findFirst(
                        "SELECT * FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = ?",
                        parentId, taxonomy);
                if (parentTaxonomy == null) {
                    throw new RepositoryException("父级分类项不存在").withContext("parentId", parentId).withContext("taxonomy", taxonomy);
                }
            }

            int updatedCount = 0;
            for (BigInteger termId : termIds) {
                TermTaxonomy termTaxonomy = TermTaxonomy.dao.findFirst(
                        "SELECT * FROM wp_term_taxonomy WHERE term_id = ? AND taxonomy = ?",
                        termId, taxonomy);

                if (termTaxonomy != null) {
                    termTaxonomy.setParent(parentId != null ? parentId : BigInteger.ZERO);
                    if (termTaxonomy.update()) {
                        updatedCount++;
                    }
                }
            }

            log.info("批量更新分类项父级完成，总数: %s, 成功: %s, 父级: %s",
                    termIds.size(), updatedCount, parentId);
            return updatedCount;
        });
    }

    /**
     * 清理分类项缓存
     *
     * @param termIds 分类项ID列表
     * @param taxonomy 分类法类型
     * @return 清理是否成功
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public boolean cleanTermCache(List<BigInteger> termIds, String taxonomy) {
        // 参数验证
        if (termIds == null || termIds.isEmpty()) {
            throw new RepositoryException("分类项ID列表不能为空").withContext("termIds", termIds);
        }
        if (StrKit.isBlank(taxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", taxonomy);
        }

        return executeDataOperation("清理分类项缓存", () -> {
            // 这里使用Ehcache，实际项目中根据具体缓存实现调整
            // CacheKit.removeAll("termCache");

            // 记录缓存清理操作
            for (BigInteger termId : termIds) {
                log.debug("清理分类项缓存，term_id: %s, taxonomy: %s", termId, taxonomy);
                // 实际缓存清理逻辑根据具体缓存框架实现
                // CacheKit.remove("termCache", termId.toString());
            }

            log.info("分类项缓存清理完成，数量: %s", termIds.size());
            return true;
        });
    }

    /**
     * 复制分类项元数据
     *
     * @param sourceTermId 源分类项ID
     * @param targetTermId 目标分类项ID
     * @return 复制是否成功
     * @throws RepositoryException 数据访问异常
     */
    @Override
    public boolean copyTermMeta(BigInteger sourceTermId, BigInteger targetTermId) {
        long startTime = System.currentTimeMillis();

        return executeWithTiming("复制分类项元数据", () -> {
            return executeDataOperation("复制分类项元数据", () -> {
                // 参数验证
                if (sourceTermId == null || targetTermId == null) {
                    throw new RepositoryException("分类项ID不能为空").withContext("sourceTermId", sourceTermId).withContext("targetTermId", targetTermId);
                }

                // 检查源分类项是否存在
                Terms sourceTerm = Terms.dao.findById(sourceTermId);
                if (sourceTerm == null) {
                    throw new RepositoryException("源分类项不存在").withContext("sourceTermId", sourceTermId);
                }

                // 检查目标分类项是否存在
                Terms targetTerm = Terms.dao.findById(targetTermId);
                if (targetTerm == null) {
                    throw new RepositoryException("目标分类项不存在").withContext("targetTermId", targetTermId);
                }

                // 获取源分类项的所有元数据
                List<Record> sourceMetaList = Db.find(
                        "SELECT meta_key, meta_value FROM wp_termmeta WHERE term_id = ?",
                        sourceTermId
                );

                if (sourceMetaList.isEmpty()) {
                    log.debug("源分类项没有元数据，无需复制: termId=%s", sourceTermId);
                    return true; // 没有元数据也视为成功
                }

                int copiedCount = 0;

                // 逐条复制元数据
                for (Record metaRecord : sourceMetaList) {
                    String metaKey = metaRecord.getStr("meta_key");
                    Object metaValue = metaRecord.get("meta_value");

                    if (StrKit.isBlank(metaKey)) {
                        continue; // 跳过空的meta_key
                    }

                    // 检查目标分类项是否已存在相同的meta_key
                    Record existingMeta = Db.findFirst(
                            "SELECT meta_id FROM wp_termmeta WHERE term_id = ? AND meta_key = ?",
                            targetTermId, metaKey
                    );

                    if (existingMeta != null) {
                        // 已存在则更新
                        Db.update(
                                "UPDATE wp_termmeta SET meta_value = ? WHERE term_id = ? AND meta_key = ?",
                                metaValue, targetTermId, metaKey
                        );
                    } else {
                        // 不存在则插入
                        Termmeta newMeta = new Termmeta();
                        newMeta.setTermId(targetTermId);
                        newMeta.setMetaKey(metaKey);
                        newMeta.setMetaValue(String.valueOf(metaValue));
                        newMeta.save();
                    }

                    copiedCount++;
                }

                log.info("分类项元数据复制完成: sourceTermId=%s, targetTermId=%s, copiedCount=%s",
                        sourceTermId, targetTermId, copiedCount);

                return true;
            });
        });
    }

    // ========== 私有工具方法 ==========

    /**
     * 验证创建命令参数
     *
     * @param command 创建命令
     * @throws RepositoryException 当参数无效时抛出
     */
    private void validateCreateCommand(TermCreateCommand command) {
        if (command == null) {
            throw new RepositoryException("创建命令不能为空").withContext("command", command);
        }
        if (StrKit.isBlank(command.getName())) {
            throw new RepositoryException("分类项名称不能为空").withContext("name", command.getName());
        }
        if (StrKit.isBlank(command.getTaxonomy())) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", command.getTaxonomy());
        }
    }

    /**
     * 验证更新命令参数
     *
     * @param command 更新命令
     * @throws RepositoryException 当参数无效时抛出
     */
    private void validateUpdateCommand(TermUpdateCommand command) {
        if (command == null) {
            throw new RepositoryException("更新命令不能为空").withContext("command", command);
        }
        if (command.getTermId() == null) {
            throw new RepositoryException("分类项ID不能为空").withContext("termId", command.getTermId());
        }
    }

    /**
     * 验证分类项ID有效性
     *
     * @param termId 分类项ID
     * @throws RepositoryException 当ID无效时抛出
     */
    private void validateTermId(BigInteger termId) {
        if (termId == null) {
            throw new RepositoryException("分类项ID不能为空").withContext("termId", termId);
        }
        if (termId.compareTo(BigInteger.ZERO) <= 0) {
            throw new RepositoryException("分类项ID必须为正整数").withContext("termId", termId);
        }
    }

    /**
     * 验证分类法类型有效性
     *
     * @param taxonomy 分类法类型
     * @throws RepositoryException 当分类法类型无效时抛出
     */
    private void validateTaxonomy(String taxonomy) {
        if (StrKit.isBlank(taxonomy)) {
            throw new RepositoryException("分类法类型不能为空").withContext("taxonomy", taxonomy);
        }
        // 可选：添加分类法类型白名单验证
        // List<String> allowedTaxonomies = Arrays.asList("category", "post_tag", "nav_menu");
        // if (!allowedTaxonomies.contains(taxonomy)) {
        //     throw new RepositoryException("不支持的分类法类型").withContext("taxonomy", taxonomy);
        // }
    }

    /**
     * 生成唯一别名
     *
     * @param name 分类项名称
     * @param taxonomy 分类法类型
     * @throws RepositoryException 当参数无效时抛出
     * @return 唯一别名
     */
    private String generateUniqueSlug(String name, String taxonomy) {
        if (StrKit.isBlank(name)) {
            throw new RepositoryException("分类项名称不能为空").withContext("name", name);
        }

        String baseSlug = SlugKit.slugify(name);

        // 修复：确保基础别名长度不超过字段限制（200字符）
        if (baseSlug.length() > 190) { // 预留10字符给后缀
            baseSlug = baseSlug.substring(0, 190);
        }

        String slug = baseSlug;
        int counter = 1;

        // 检查别名是否唯一
        while (isSlugExists(slug, taxonomy, null)) {
            // 修复：确保生成的别名不超过字段长度限制
            String suffix = "-" + counter;
            if (baseSlug.length() + suffix.length() > 200) {
                // 如果基础名过长，截断并添加计数器
                int maxBaseLength = 200 - suffix.length();
                slug = baseSlug.substring(0, maxBaseLength) + suffix;
            } else {
                slug = baseSlug + suffix;
            }
            counter++;

            // 防止无限循环 - 修复：使用更安全的后缀生成方式
            if (counter > 1000) {
                // 使用纳秒时间戳作为后缀，确保唯一性
                String nanoSuffix = "-" + System.nanoTime();
                int maxBaseLength = 200 - nanoSuffix.length();
                if (maxBaseLength > 0) {
                    slug = baseSlug.substring(0, maxBaseLength) + nanoSuffix;
                } else {
                    // 极端情况：基础名本身就接近200字符
                    slug = nanoSuffix.substring(1); // 去掉开头的-
                }
                log.warn("别名生成达到最大重试次数，使用时间戳后缀: baseSlug=%s", baseSlug);
                break;
            }
        }

        return slug;
    }

    /**
     * 检查别名是否存在（排除指定分类项）
     *
     * @param slug 别名
     * @param taxonomy 分类法类型
     * @param excludeTermId 排除的分类项ID
     * @return 是否存在
     */
    private Boolean isSlugExists(String slug, String taxonomy, BigInteger excludeTermId) {
        try {
            StringBuilder sql = new StringBuilder();
            sql.append("SELECT COUNT(*) as count FROM wp_terms t ");
            sql.append("INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id ");
            sql.append("WHERE t.slug = ? AND tt.taxonomy = ? ");

            if (excludeTermId != null) {
                sql.append("AND t.term_id != ?");
            }

            Record record;
            if (excludeTermId != null) {
                record = Db.findFirst(sql.toString(), slug, taxonomy, excludeTermId);
            } else {
                record = Db.findFirst(sql.toString(), slug, taxonomy);
            }

            return record != null && record.getLong("count") > 0;

        } catch (Exception e) {
            log.error("检查分类项别名是否存在异常", e);
            return false;
        }
    }
}